package com.ardf.util;

import com.ardf.entity.Print;
import com.ardf.service.CardWebSocketService;
import com.profesorfalken.wmi4java.WMI4Java;
import com.profesorfalken.wmi4java.WMIClass;

import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.Attribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
import javax.print.attribute.standard.PrinterState;
import javax.print.attribute.standard.PrinterStateReasons;
import java.awt.*;
import java.awt.print.*;
import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class PrintGrade implements Printable {
    int height = 0;

    private CardWebSocketService webSocketService;

    private Long id;//websocket的id

    private Print grade;

    private Boolean isRelay; //是否是接力赛


    public PrintGrade(Print printGrade, CardWebSocketService webSocketService, Long id, Boolean isRelay) {
        this.grade = printGrade;
        this.webSocketService = webSocketService;
        this.id = id;
        this.isRelay = isRelay;
    }

    public PrintGrade(Print printGrade, Boolean isRelay) {
        this.grade = printGrade;
        this.isRelay = isRelay;
    }

    private int printMessage(Graphics2D g2d, int totalHeight) {
        Font font = new Font("宋体", Font.PLAIN, 8);
        g2d.setFont(font);
        FontMetrics fontMetrics = g2d.getFontMetrics(font);

        String competitionName = this.grade.getCompetitionName() != null ? this.grade.getCompetitionName() : "";
        //打印赛事名称，名字过长双行显示
        if (competitionName.length() > 16) {
            int first_index = (int) (competitionName.length() * 0.45);
            int padding1 = 130 - fontMetrics.stringWidth(competitionName.substring(0, first_index + 2));
            int padding2 = 130 - fontMetrics.stringWidth(competitionName.substring(first_index + 2, competitionName.length()));
            g2d.drawString(competitionName.substring(0, first_index + 2), padding1 / 2, totalHeight + 8);
            totalHeight += 12;
            g2d.drawString(competitionName.substring(first_index + 2, competitionName.length()), padding2 / 2, totalHeight + 8);
            totalHeight += 12;
        } else {
            int padding = 128 - competitionName.length() * 8;
            g2d.drawString(competitionName, padding / 2, totalHeight + 8);
            totalHeight += 12;
        }
        g2d.setFont(new Font("宋体", Font.PLAIN, 8));
        g2d.drawString("********************************************", 0, totalHeight + 8);
        totalHeight += 12;

        g2d.setFont(new Font("宋体", Font.PLAIN, 6));
        String organization = "主办单位：" + (this.grade.getCompetitionOrganization() != null ? this.grade.getCompetitionOrganization() : "");
        g2d.drawString(organization, 0, totalHeight + 6);
        totalHeight += 10;

        String date = "比赛日期：" + (this.grade.getDate() != null ? this.grade.getDate() : "");
        g2d.drawString(date, 0, totalHeight + 6);
        totalHeight += 10;

        String project = "比赛项目：" + (this.grade.getProject() != null ? this.grade.getProject() : "");
        g2d.drawString(project, 0, totalHeight + 6);
        totalHeight += 10;


        g2d.setFont(new Font("宋体", Font.PLAIN, 8));
        g2d.drawString("********************************************", 0, totalHeight + 8);
        totalHeight += 12;

        g2d.setFont(new Font("宋体", Font.PLAIN, 6));
        g2d.drawString("成 绩 单", 55, totalHeight + 6);
        totalHeight += 10;

        if (!isRelay) {
            String name = this.grade.getAthleteName() != null ? this.grade.getAthleteName() : "";
            g2d.drawString("姓名：" + name, 0, totalHeight + 6);

            String group = this.grade.getGroup() != null ? this.grade.getGroup() : "";
            g2d.drawString("组别：" + group, 66, totalHeight + 6);
            totalHeight += 10;
        } else {
            String name = this.grade.getTeamName() != null ? this.grade.getTeamName() : "";
            g2d.drawString("接力队伍：" + name, 0, totalHeight + 6);
            totalHeight += 10;

            String group = this.grade.getGroup() != null ? this.grade.getGroup() : "";
            g2d.drawString("组别：" + group, 0, totalHeight + 6);
            totalHeight += 10;
        }

        if (!isRelay) {
            String card = this.grade.getCard() != null ? this.grade.getCard() : "";
            g2d.drawString("卡号：" + card, 0, totalHeight + 6);
            String number = this.grade.getNumber() != null ? this.grade.getNumber() : "";
            g2d.drawString("号码：" + number, 66, totalHeight + 6);
        } else {
            String athleteNames = "";
            for (int i = 0; i < this.grade.getAthleteNames().size(); i++) {
                if (i < this.grade.getAthleteNames().size() - 1) {
                    athleteNames = athleteNames + this.grade.getAthleteNames().get(i) + "、";
                } else {
                    athleteNames = athleteNames + this.grade.getAthleteNames().get(i);
                }

            }

            g2d.drawString("运动员：" + athleteNames, 0, totalHeight + 6);
        }
        totalHeight += 10;


        if (this.grade.getCount() != null) {
            String stationNum = String.valueOf(this.grade.getCount());
            g2d.drawString("站数：" + stationNum, 0, totalHeight + 6);
        } else {
            g2d.drawString("站数：", 0, totalHeight + 6);
        }

        if (this.grade.getTime() != null) {
            String time = this.grade.getTime();
            g2d.drawString("用时：" + time, 66, totalHeight + 6);
        } else {
            g2d.drawString("用时：", 66, totalHeight + 6);
        }
        totalHeight += 10;

        g2d.setFont(new Font("宋体", Font.PLAIN, 8));
        g2d.drawString("********************************************", 0, totalHeight + 8);
        totalHeight += 12;

        g2d.setFont(new Font("宋体", Font.PLAIN, 6));

        g2d.drawString("序号", 0, totalHeight + 6);
        g2d.drawString("站号", 18, totalHeight + 6);
        g2d.drawString("到站时刻", 48, totalHeight + 6);
        g2d.drawString("站间用时", 95, totalHeight + 6);
        totalHeight += 10;
        if (this.grade.getSequences() != null && this.grade.getSequences().size() > 0) {
            g2d.drawString(this.grade.getSequences().get(0), 0, totalHeight + 6);
            g2d.drawString(this.grade.getRoutes().get(0), 18, totalHeight + 6);
            g2d.drawString(this.grade.getTimeList().get(0), 48, totalHeight + 6);
            totalHeight += 10;
            for (int i = 1; i < this.grade.getSequences().size(); i++) {
                g2d.drawString(this.grade.getSequences().get(i), 0, totalHeight + 6);
                g2d.drawString(this.grade.getRoutes().get(i), 18, totalHeight + 6);
                g2d.drawString(this.grade.getTimeList().get(i), 48, totalHeight + 6);

                Duration duration = Duration.between(LocalTime.parse(this.grade.getTimeList().get(i - 1)), LocalTime.parse(this.grade.getTimeList().get(i)));
                long totalSeconds = duration.getSeconds();
                int nanos = duration.getNano();
                int hours = (int) totalSeconds / 3600;
                int minutes = (int) (totalSeconds % 3600) / 60;
                int seconds = (int) totalSeconds % 60;
                LocalTime rtime = LocalTime.of(hours, minutes, seconds, nanos);
                g2d.drawString(rtime.format(DateTimeFormatter.ofPattern("HH:mm:ss")), 95, totalHeight + 6);
                totalHeight += 10;
            }
        }

        g2d.setFont(new Font("宋体", Font.PLAIN, 8));
        g2d.drawString("********************************************", 0, totalHeight + 8);
        totalHeight += 12;

        return totalHeight;


    }


    @Override
    public int print(Graphics g, PageFormat pf, int page) throws PrinterException {

        if (page > 0) {
            return NO_SUCH_PAGE;
        }
        Graphics2D g2d = (Graphics2D) g;
        g2d.translate(pf.getImageableX(), pf.getImageableY());

        height = printMessage(g2d, height);
        return PAGE_EXISTS;
    }


    public Boolean printGrade() {
        //PageFormat类描述要打印的页面大小和方向
        PageFormat pf = new PageFormat();  //初始化一个页面打印对象
        pf.setOrientation(PageFormat.PORTRAIT); //设置页面打印方向，从上往下，从左往右

        Paper paper = new Paper();
        paper.setSize(165, 100000);// 纸张大小
        paper.setImageableArea(4, 0, 153, 100000); //设置打印区域，A4纸的默认X,Y边距是72
        pf.setPaper(paper);

        Book book = new Book();
        book.append(new PrintGrade(this.grade, this.webSocketService, this.id, this.isRelay), pf);


        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPageable(book);
        System.out.println("11111111111");
        //获取不脱机的所有打印机设备
//        String rawOutput = WMI4Java
//                .get()
//                .properties(Arrays.asList("Name", "WorkOffline"))
//                .filters(Arrays.asList("$_.WorkOffline -eq 0"))
//                .getRawWMIObjectOutput(WMIClass.WIN32_PRINTER);
//        System.out.println("11111111111");
//        //处理输出格式
//        List<String> printers = Arrays.stream(rawOutput.split("(\r?\n)"))
//                .filter(line -> line.startsWith("Name"))
//                .map(line -> line.replaceFirst(".* : ", ""))
//                .sorted()
//                .collect(Collectors.toList());
//        System.out.println(printers);


        try {
            PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
            for (PrintService printService : printServices) {
                System.out.println(printService.getName());
                System.out.println(printService.getAttribute(PrinterState.class));
                if (printService.getName().equals("GP-5830 Series")) {
                    job.setPrintService(printService);
                    job.print();

                    if (this.webSocketService != null)
                        this.webSocketService.sendMessageToUser(this.id, "请放置指卡");
                    return true;
                }

            }

            if (this.webSocketService != null)
                this.webSocketService.sendMessageToUser(this.id, "打印失败！请连接打印机");
            return false;
        } catch (PrinterException e) {
            throw new RuntimeException(e);
        }

    }

}
